package com.codefish.codefish_blog.controller;

import com.codefish.codefish_blog.ajax.AjaxResult;
import com.codefish.codefish_blog.config.property.BlogWebProperties;
import com.codefish.codefish_blog.entity.User;
import com.codefish.codefish_blog.exception.AccountException;
import com.codefish.codefish_blog.service.UserService;
import com.codefish.codefish_blog.utils.CookieUtil;
import com.codefish.codefish_blog.utils.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户信息相关controller类
 *
 * @author codefish
 * @version 1.0
 * @date 2022/03/26 下午 08:37
 */
@RestController
@Slf4j
@RequestMapping("/user")
public class UserController {
    @Autowired
    UserService userService;

    /**
     * 处理用户登录请求
     *
     * @param account  用户输入的账号
     * @param password 用户输入的密码
     * @return 登录验证结果
     */
    @PostMapping("/login")
    public AjaxResult doLogin(String account, String password, HttpServletResponse response) {
        AjaxResult result;
        Map<String, Object> resultMap = new HashMap<>(2);
        User user = userService.doLogin(account, password);
        if (user != null) {
            //初始化token携带的数据
            Map<String, Object> map = new HashMap<>(2);
            map.put("id", user.getId());
            //签发token
            String token = JwtUtil.createJwtToken(map);
            //设置cookie，保存用户的信息
            String cookieVal = user.getId() + "_" + user.getUsername();
            CookieUtil.setCookie(response, BlogWebProperties.USER_INFO_PROPERTY, cookieVal, JwtUtil.EXPIRE_TIME.intValue(), "/");
            //初始化resultMap
            resultMap.put("username", user.getUsername());
            resultMap.put("token", token);
            result = AjaxResult.success("登录成功", resultMap);
        } else {
            throw new AccountException("账号或密码错误");
        }
        return result;
    }

    /**
     * 处理用户注册请求
     *
     * @param account  用户输入的账号
     * @param password 用户输入的密码
     * @return 用户注册结果
     */
    @PostMapping("/register")
    public AjaxResult doReg(String account, String password, HttpServletResponse response) {
        AjaxResult result;
        Map<String, Object> resultMap = new HashMap<>(2);
        User user = userService.doRegister(account, password);
        if (user != null) {
            //初始化token携带的数据
            Map<String, Object> map = new HashMap<>(2);
            map.put("id", user.getId());
            //签发token
            String token = JwtUtil.createJwtToken(map);
            //设置cookie，保存用户的信息
            String cookieVal = user.getId() + "_" + user.getUsername();
            CookieUtil.setCookie(response, BlogWebProperties.USER_INFO_PROPERTY, cookieVal, JwtUtil.EXPIRE_TIME.intValue(), "/");
            //初始化resultMap
            resultMap.put("token", token);
            result = AjaxResult.success("注册成功", resultMap);
        } else {
            throw new AccountException("账号已存在");
        }
        return result;
    }

    /**
     * 用户退出登录
     *
     * @param session session对象
     * @return 退出登录结果
     */
    @PostMapping("/offline")
    public AjaxResult doOffLine(HttpSession session, HttpServletResponse response) {
        User user = (User) session.getAttribute(BlogWebProperties.USER_INFO_PROPERTY);
        if (user == null) {
            return AjaxResult.fail("当前用户没有登录");
        } else {
            //获取下线时间
            Date leaveTime = new Date();
            log.info("{}退出登录，下线时间:{}", user.getUsername(), leaveTime);
            //清除session中的userInfo
            session.removeAttribute(BlogWebProperties.USER_INFO_PROPERTY);
            //使客户端本地cookie过期(设置过期时间为0)
            CookieUtil.setCookie(response, BlogWebProperties.USER_INFO_PROPERTY, null, 0, "/");
            //将下线时间发给客户端
            return AjaxResult.success("用户成功退出登录", leaveTime);
        }
    }
}
